package es.efor.ics.gev.dao.jpa;

import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.persistence.Query;

import org.springframework.stereotype.Repository;

import es.efor.ics.gev.dao.AtributoMaestroDao;
import es.efor.ics.gev.model.AtributoMaestro;

/**
 * This class interacts with EntityManager to save/delete and retrieve
 * AtributoMaestro objects.
 * 
 * @author dlisbona
 * 
 */
@Repository("atributoMaestroDao")
public class AtributoMaestroDaoJpa extends GenericDaoJpa<AtributoMaestro, Long>
		implements AtributoMaestroDao {

	/**
	 * Constructor that sets the entity to AtributoMaestro.class.
	 */
	public AtributoMaestroDaoJpa() {
		super(AtributoMaestro.class);
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	public List<AtributoMaestro> getAtributos() {
		return getEntityManager().createNamedQuery("findAllAtributos")
				.getResultList();
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	public SortedSet<AtributoMaestro> getOrderedSetAtributos() {
		List result = getEntityManager().createNamedQuery("findAllAtributos")
				.getResultList();
		SortedSet<AtributoMaestro> resultOrdered = new TreeSet<AtributoMaestro>();
		resultOrdered.addAll(result);
		return resultOrdered;
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	public List<AtributoMaestro> getAtributosByNombre(String nombreAtributo) {
		String value = '%' + nombreAtributo.toUpperCase() + '%';
		return getEntityManager().createNamedQuery("findAtributosByNombre")
				.setParameter("nombre", value).getResultList();
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	public List<AtributoMaestro> getAtributosByNombreAndCategoria(
			String nombreAtributo, Long categoriaAtributoId) {
		String value = '%' + nombreAtributo.toUpperCase() + '%';
		return getEntityManager().createNamedQuery(
				"findAtributosByNombreAndCategoriaId").setParameter("nombre",
				value).setParameter("id", categoriaAtributoId).getResultList();
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	public List<AtributoMaestro> getAtributosByNombreAndTipo(
			String nombreAtributo, Long tipoAtributoId) {
		String value = '%' + nombreAtributo.toUpperCase() + '%';
		return getEntityManager().createNamedQuery("findAtributosByNombreAndTipo")
				.setParameter("nombre", value)
				.setParameter("id", tipoAtributoId)
				.getResultList();
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	public List<AtributoMaestro> getAtributosByCategoria(
			Long categoriaAtributoId) {
		return getEntityManager()
				.createNamedQuery("findAtributosByCategoriaId").setParameter(
						"id", categoriaAtributoId).getResultList();
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	public List<AtributoMaestro> getAtributosByNombreCategoria(
			String nombreCategoriaAtributo) {
		String value = '%' + nombreCategoriaAtributo.toUpperCase() + '%';
		return getEntityManager().createNamedQuery(
				"findAtributosByNombreCategoria").setParameter("nombre", value)
				.getResultList();
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	public List<AtributoMaestro> getAtributosByNombreCategoriaExacto(
			String nombreCategoriaAtributo) {
		String value = nombreCategoriaAtributo.toUpperCase();
		return getEntityManager().createNamedQuery(
				"findAtributosByNombreCategoriaExacto").setParameter("nombre",
				value).getResultList();
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	public List<AtributoMaestro> getAtributosByTipo(Long tipoAtributoId) {
		return getEntityManager().createNamedQuery("findAtributosByTipo")
				.setParameter("id", tipoAtributoId).getResultList();
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	public List<AtributoMaestro> getAtributosByTipoAndCategoria(
			Long tipoAtributoId, Long categoriaAtributoId) {
		Query q = getEntityManager().createNamedQuery(
				"findAtributosByTipoAndCategoria");
		q.setParameter("tipoId", tipoAtributoId);
		q.setParameter("catId", categoriaAtributoId);
		return q.getResultList();
	}

	/**
	 * {@inheritDoc}
	 */
	@SuppressWarnings("unchecked")
	public List<AtributoMaestro> getAtributosByNombreAndTipoAndCategoria(
			String nombre, Long tipoAtributoId, Long categoriaAtributoId) {
		String value = '%' + nombre.toUpperCase() + '%';
		Query q = getEntityManager().createNamedQuery(
				"findAtributosByNombreAndTipoAndCategoria");
		q.setParameter("nombre", value);
		q.setParameter("tipoId", tipoAtributoId);
		q.setParameter("catId", categoriaAtributoId);
		return q.getResultList();
	}

	/**
	 * {@inheritDoc}
	 */
	public AtributoMaestro saveAtributo(AtributoMaestro atributo) {
		log.debug("atributo's id: " + atributo.getId());
		AtributoMaestro a = getEntityManager().merge(atributo);
		getEntityManager().flush();
		return a;
	}

	@Override
	public AtributoMaestro save(AtributoMaestro atributo) {
		return this.saveAtributo(atributo);
	}

}
